package com.example.mcu_up.serial;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;

import android.util.Log;

public class Mcu_Pack implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1000L;
	private byte header;
	private byte type;// 类型
	private static int len = 0;// 长度
	private byte[] data;// 数据
	private int check;
	private byte end;

	public byte getEnd() {
		return end;
	}

	public void setEnd(byte end) {
		this.end = end;
	}

	public byte getHeader() {
		return header;
	}

	public void setHeader(byte header) {
		this.header = header;
	}

	public int getCheck() {
		return check;
	}

	public void setCheck(int check) {
		this.check = check;
	}

	public byte getType() {
		return type;
	}

	public void setType(byte type) {
		this.type = type;
	}

	public int getLen() {
		return len;
	}

	public void setLen(int len) {
		this.len = len;
	}

	public byte[] getData() {
		return data;
	}

	public void setData(byte[] data) {
		this.data = data;
	}

	// byte 数组与 int 的相互转换
	public static int byteArrayToInt(byte[] b) {
		return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16
				| (b[0] & 0xFF) << 24;
	}

	public static byte[] intToByteArray(int a) {
		return new byte[] { (byte) ((a >> 24) & 0xFF),
				(byte) ((a >> 16) & 0xFF), (byte) ((a >> 8) & 0xFF),
				(byte) (a & 0xFF) };
	}

	/**
	 * 将int数值转换为占四个字节的byte数组，本方法适用于(高位在前，低位在后)的顺序。 和bytesToInt2（）配套使用
	 */
	public static byte[] intToBytes_M(int value) {
		byte[] src = new byte[2];

		src[0] = (byte) ((value >> 8) & 0xFF);
		src[1] = (byte) (value & 0xFF);
		return src;
	}

	/**
	 * byte数组中取int数值，本方法适用于(高位在前，低位在后)的顺序。和intToBytes2（）配套使用
	 */

	public static int bytesToInt_M(byte[] src, int offset) {
		int value;
		value = (int) ((src[offset] & 0xFF) << 8) | (src[offset + 1] & 0xFF);
		return value;
	}

	/**
	 * 将int数值转换为占四个字节的byte数组，本方法适用于(低位在前，高位在后)的顺序。 和bytesToInt2（）配套使用
	 */
	/*
	 * public static byte[] intToBytes_L(int value) { byte[] abyte0 = new
	 * byte[2];
	 * 
	 * abyte0[0] = (byte) (0xff & value);
	 * 
	 * 
	 * abyte0[1] = (byte) (0xff & (value >> 8));
	 * 
	 * return abyte0;
	 * 
	 * }
	 */
	/**
	 * 将int数值转换为占四个字节的byte数组，本方法适用于(低位在前，高位在后)的顺序。 和bytesToInt（）配套使用
	 * 
	 * @param value
	 *            要转换的int值
	 * @return byte数组
	 */
	public static byte[] intToBytes_L(int value) {
		byte[] src = new byte[2];

		src[1] = (byte) ((value >> 8) & 0xFF);
		src[0] = (byte) (value & 0xFF);
		return src;
	}

	/**
	 * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序。和intToBytes2（）配套使用
	 */

	/*
	 * public static int bytesToInt_L(byte[] src) { int addr = (0xFF&src[0]);
	 * 
	 * addr |= (0xFF&(src[1]<<8));
	 * 
	 * return addr; }
	 */

	public static int bytesToInt_L(byte[] res) {
		// res = InversionByte(res);
		// 一个byte数据左移24位变成0x??000000，再右移8位变成0x00??0000
		Log.e("getpack1", "第一个数" + String.valueOf(res[0] & 0xff));

		Log.e("getpack1", "第二个数" + String.valueOf(res[1]));

		int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00);

		return targets;
	}

	public static int bytesToInt3(byte[] src, int offset) {
		int value;
		value = (int) ((src[offset] & 0xFF) << 16)
				| ((src[offset + 1] & 0xFF) << 8) | (src[offset + 2] & 0xFF);
		return value;
	}

	/**
	 * 将32位的int值放到4字节的里
	 * 
	 * @param num
	 * @return
	 */
	public static byte[] int2byteArray(int num) {
		byte[] result = new byte[4];
		result[0] = (byte) (num >>> 24);// 取最高8位放到0下标
		result[1] = (byte) (num >>> 16);// 取次高8为放到1下标
		result[2] = (byte) (num >>> 8); // 取次低8位放到2下标
		result[3] = (byte) (num); // 取最低8位放到3下标
		return result;
	}

	/**
	 * 将4字节的byte数组转成一个int值
	 * 
	 * @param b
	 * @return
	 */
	public static int byteArray2int(byte[] b) {
		byte[] a = new byte[4];
		int i = a.length - 1, j = b.length - 1;
		for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
			if (j >= 0)
				a[i] = b[j];
			else
				a[i] = 0;// 如果b.length不足4,则将高位补0
		}
		int v0 = (a[0] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
		int v1 = (a[1] & 0xff) << 16;
		int v2 = (a[2] & 0xff) << 8;
		int v3 = (a[3] & 0xff);
		return v0 + v1 + v2 + v3;
	}

	/*
	 * byte为一位数的时候用
	 */
	public static int readOne(byte[] b) {
		int a = -1;
		DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
		try {
			a = dis.readByte();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;
	}

	/*
	 * 1,2时候用
	 */
	public static int[] readOneTwo(byte[] b) {
		int[] a = new int[2];
		DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));

		try {
			a[0] = dis.readByte();
			a[1] = dis.readShort();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;
	}

	/*
	 * 2,2时候用
	 */
	public static int[] readTwoTwo(byte[] b) {
		int[] a = new int[2];
		DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
		byte[] res = new byte[4];
		try {

			res[0] = dis.readByte();
			res[1] = dis.readByte();
			res[2] = dis.readByte();
			res[3] = dis.readByte();

			a[0] = (res[0] & 0xff) | ((res[1] << 8) & 0xff00);
			a[1] = (res[2] & 0xff) | ((res[3] << 8) & 0xff00);
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;
	}

	/*
	 * 1,2,2时候用
	 */
	public static int[] readOneTwoTwo(byte[] b) {
		int[] a = new int[3];
		DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
		try {
			a[0] = dis.readByte();
			a[1] = dis.readShort();
			a[2] = dis.readShort();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;
	}

	/*
	 * 4,1,3时候用
	 */
	public static int[] readFourOneThree(byte[] b) {
		int[] a = new int[3];
		byte[] c = new byte[3];
		DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
		try {
			a[0] = dis.readInt();
			a[1] = dis.readByte();
			c[0] = dis.readByte();
			c[1] = dis.readByte();
			c[2] = dis.readByte();
			a[2] = Mcu_Pack.bytesToInt3(c, 0);

		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return a;
	}

	/*
	 * 应答码时候用
	 */
	public static String answer(byte[] b) {
		String a = null;
		DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
		try {
			a = dis.readByte() == 1 ? "OK" : "Error";
		} catch (IOException e) {

			e.printStackTrace();
		}
		return a;
	}

	public int readShort(DataInputStream is) {
		byte[] b = new byte[2];
		try {
			b[0] = is.readByte();
			b[1] = is.readByte();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return bytesToInt_L(b);
	}

	/*
	 * 接收包，如果type类型 为0x00就是应答包，如果不是就是正常 的包
	 */

	public Mcu_Pack getPack(InputStream is) throws IOException,
			BadPackageException {

		Mcu_Pack p = new Mcu_Pack();
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		DataInputStream dis = new DataInputStream(is);
		header = dis.readByte();

		if (header != (byte) 0x01) {
			Log.i("myheaderis", String.valueOf(header));
			throw new BadPackageException("wrong synchronize header." + header);
		}

		type = dis.readByte();
		if (!(type == 0x00 || type == 0x02 || type == 0x03 || type == 0x04
				|| type == 0x05 || type == 0x06 || type == 0x07 || type == 0x08
				|| type == 0x09 || type == 0x0A || type == 0x0c || type == 0x0D || type == 0x0f)) {
			throw new BadPackageException("wrong synchronize type." + type);
		}

		p.setType(type);
		len = readShort(dis);
		p.setLen(len);

		int remaining = len;
		byte[] buf = new byte[1024];
		while (remaining > 0) {

			int c = dis.read(buf, 0, remaining > 1024 ? 1024 : remaining);
			outputStream.write(buf, 0, c);
			remaining -= c;
		}
		p.setData(outputStream.toByteArray());

		check = readShort(dis);
		Log.e("getpack1", String.valueOf(check));
		p.setCheck(check);
		end = dis.readByte();
		p.setEnd(end);

		return p;
	}

	/*
	 *
	 */
	public byte[] tobytes() {
		header = (byte) 0x01;
		ByteBuffer b = null;
		if (getData() != null && getData().length > 0)
			len = getData().length;
		else
			len = 0;
		b = ByteBuffer.allocate(len + 7);
		b.put(header);// 头1
		b.put(type);// 类型1
		b.put(intToBytes_L(len));// 长度2
		if (len != 0) {
			b.put(getData());
		}
		int check = CRC16.CyBtldr_ComputeChecksum(b.array(),
				b.array().length - 3);
		b.put(intToBytes_L(check));// 校验码
		b.put((byte) 0x17);
		return b.array();

	}

	public static String byteToString(byte[] b) {
		StringBuffer buffer = new StringBuffer(b.length);
		for (int i = 0; i < b.length; i++) {
			String strHex = Integer.toHexString(b[i]).toUpperCase();
			if (strHex.length() > 3) {
				buffer.append(strHex.substring(6) + " ");
			} else if (strHex.length() < 2) {
				buffer.append("0" + strHex + " ");

			} else {
				buffer.append(strHex + " ");
			}
		}
		return buffer.toString();

	}

}
